All computer software programs need to be debugged and tested to ensure that they properly perform the tasks they are designed to perform. The act of identifying cause of known problems (referred to as bugs) and fixing these problems in a program is called “debugging” the program.
One way to debug a computer program is to insert output statement at various points in the program. The output of these statements may be directed to a debug log, where multiple elements, i.e., parameters, of a message are complied together. These output statements may be implemented as simpler print or write statements, as defined in the programming language. More typically, these output statements are implemented as calls to logging methods, giving a programmer the capability of turning debug messages on or off, altering the messages, or directing the messages to a log file.
In its simplest form, a debug message is a text string presented to a user on a screen display device or written to a file storage device. In reality, a debug message is only useful if it displays the values of interesting parameters from the program. To display these values, the program typically evaluates the parameters using CPU resources to convert these values to displayable strings. These strings are combined with other strings supplied by the user into a single string to be displayed or logged. This string concatenation process consumes additional CPU and memory resources. One of the most important causes of resource consumption is the dynamic allocation of memory to contain concatenated strings.
In a typical implementation of a debug log, even before a decision to log a message is made, all resources required to evaluate parameters and concatenate results into a displayable string have been expended. While this expense may be minor compared to actually logging the message, in a well instrumented system with thousands of debug log messages, the high volume of these messages (even if not logged) can have a significantly adverse impact on performance or the program.
String concatenation is an expensive operation in any programming language, but is particularly expensive in Java language because Java language creates a new immutable string object for each concatenation and discards the prior object at each step. This process involves expensive object creation as well as extensive fragmentation, which adversely impacts garbage collection. Garbage collection is the process of finding and recovering dynamically allocated memory and returning this memory to the pool of available memory that can be allocated as needed in the future.
Various efforts have been made to selectively enable debug logging to isolate problems, while at the same time, disabling the majority of debug logging to increase performance. One solution is to use conditional compilation to disable debug logging in production code. Conditional compilation uses compiler directives to cause certain code to be included or excluded during a compilation process. However, this solution may make the debug logging only available to the developer, and inaccessible to on-line or off-line support personnel. In addition, conditional compilation is not available in all computer languages (e.g. Java language).
Another solution is commenting out the debug logging prior to release. Commenting out means manually editing the code to convert debug logging code to comments. However, this solution is tedious and difficult to do without the risk of causing other defects associated with improper editing. In addition, if the commenting out is performed later in the development cycle, more risk is incurred; but if performed earlier, less benefit is received.
Yet another solution is removing and/or simplifying some logging to reduce the performance impact. However, the logging removed may be just the logging required to isolate a problem.
Still another solution is tolerating poor performance. However, lackluster performance may be tolerable, but is never desirable. Additionally, the impact is not only on the program containing the debug logging, but also on all programs that contend for resources on the system.